package com.zhihao.takeaway.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhihao.takeaway.common.utils.DateTool;
import com.zhihao.takeaway.common.utils.EasyUITable;
import com.zhihao.takeaway.common.utils.JwtUtil;
import com.zhihao.takeaway.entity.Dish;
import com.zhihao.takeaway.entity.DishFlavorVo;
import com.zhihao.takeaway.mapper.DishMapper;
import com.zhihao.takeaway.service.CategoryService;
import com.zhihao.takeaway.service.DishService;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper,Dish>
    implements DishService {

    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public List<DishFlavorVo> getDishFlavorData(String MarketerId) {
        List<DishFlavorVo>list = dishMapper.selectDishFlavor(MarketerId);
        return list;
    }


    @Override
    public List<Dish> selectList(String input) {
        QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(Dish::getName,input);
        List<Dish>list = dishMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public List<Dish> getMenuData(String search) {

//            判断是否是数字
        boolean isNum = false;
        int num = 0;
        search = search.trim();
        for(int i = 0 ; i < search.length() ; i++){
            if (search.charAt(i)-'0'>=0 && search.charAt(i)-'9' <= 0){
                num = num * 10 + search.charAt(i) - '0';
            }else{
                break;
            }
        }
        if(num > 0){isNum = true;}
        QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(Dish::getName,search)
                .or().like(Dish::getDescription,search)
                .or().like(Dish::getCreateTime,search)
                .or().like(Dish::getCreateUser,search)
                .or().like(Dish::getUpdateUser,search)
                .or().like(Dish::getId,search);
        if(isNum){
            queryWrapper.lambda()
                    .gt(Dish::getPrice,num-num*0.2)
                    .lt(Dish::getPrice,num+num*0.2)
                    .or().eq(Dish::getCode,num)
                    .or().eq(Dish::getStatus,num);
        }
        List<Dish> list = dishMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public Boolean sailDish(Dish dish) {

        String EmployeeId = getEmployeeId();
        dish.setUpdateUser(EmployeeId);
        dish.setUpdateTime(DateTool.getCurrTime());
        dish.setStatus(1);
        int num = dishMapper.updateById(dish);
        if(num == 1){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Boolean addDish(Dish dish) {
            dishMapper.insert(dish);
            return true;
    }

    @Override
    public Boolean stopDish(Dish dish) {
        String EmployeeId = getEmployeeId();
        dish.setUpdateUser(EmployeeId);
        dish.setUpdateTime(DateTool.getCurrTime());
        dish.setStatus(0);
        int num = dishMapper.updateById(dish);
        if(num == 1){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Boolean updateDish(Dish dish) {

        String EmployeeId = getEmployeeId();
        dish.setUpdateUser(EmployeeId);
        dish.setUpdateTime(DateTool.getCurrTime());
        int num = dishMapper.updateById(dish);
        if(num == 1){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Dish selectById(String id) {
        Dish dish = dishMapper.selectById(id);
        return dish;
    }

    @Override
    public Boolean deleteDish(Dish dish){
        int num = dishMapper.deleteById(dish.getId());
        if(num == 1){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Boolean parseContent() throws Exception {
        List<Dish> formData = dishMapper.selectList(null);
//        把查询到的数据放入es中
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");
        for(int i = 0 ; i < formData.size() ; i++){
            System.out.println(JSON.toJSONString(formData.get(i)));
            bulkRequest.add(
                    new IndexRequest("dish_search")
                            .source(JSON.toJSONString(formData.get(i)), XContentType.JSON));
        }
        BulkResponse bulkItemResponses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !bulkItemResponses.hasFailures();
    }

    @Override
    public List<Map<String, Object>> searchPage(String keyword, int pageNo, int pageSize) throws Exception{
        //        条件搜索
        SearchRequest searchRequest = new SearchRequest("dish_search");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

//        分页
        searchSourceBuilder.from(pageNo);
        searchSourceBuilder.size(pageSize);

//        模糊匹配
//        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name",keyword);
        searchSourceBuilder.query(matchQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

//        高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red;font-weight:600'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

//        执行搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//        解析结果

        ArrayList<Map<String,Object>> list = new ArrayList<>();
        for(SearchHit documentFields : search.getHits().getHits()){
//            解析高亮字段
            Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
//            把所有的标题获取出来（高亮字段的标题）
            HighlightField title = highlightFields.get("name");
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();  // 原来的未高亮的字段
//            解析高亮字段
//            把高亮字段替换为原来没有高亮的字段
//            这一步是取出高亮字段
            if(title != null){
                Text[] fragments = title.fragments();
//                新的标题
                String n_title = "";
                for(Text text:fragments){
                    n_title += text;
                }
                sourceAsMap.put("name",n_title); // 高亮字段替换掉原来的内容即可

            }
            list.add(sourceAsMap);
//            非高亮一步保存即可
            //            list.add(documentFields.getSourceAsMap());
        }
        return list;
    }

    @Override
    public EasyUITable getDishListByMarketerId(String marketerId) {

        List<DishFlavorVo> list = dishMapper.selectDishFlavor(marketerId);
        return new EasyUITable(list.size(),list);
    }

    @Override
    public List<Dish> selectByIds(String dishId) {
        String []dishIds = dishId.split(";");
        List<Dish> list = new ArrayList<>();
        for(int i = 0 ; i < dishIds.length ; i++){
            QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("name","price");
            queryWrapper.lambda().eq(Dish::getId,dishIds[i]);
            Dish dish = dishMapper.selectOne(queryWrapper);
            list.add(dish);
        }
        return list;
    }

    public String getEmployeeId(){
        String token = request.getHeader("token");
        String EmployeeId = JwtUtil.validateToken(token);
        return EmployeeId;
    }
}
